package in.co.codedoc.encrypt;

import in.co.codedoc.cg.annotations.HasProperties;
import in.co.codedoc.cg.annotations.IsAnIOCComponent;
import in.co.codedoc.cg.annotations.IsMappedToJSON;
import in.co.codedoc.cg.annotations.Property;
import in.co.codedoc.config.Configurable;
import in.co.codedoc.config.ConfigurationUtil;
import in.co.codedoc.config.Configurator;
import in.co.codedoc.ioc.IOCContainer;
import in.co.codedoc.json.JSONValue;

@IsAnIOCComponent
@IsMappedToJSON
@HasProperties
({
	@Property(name="secret",datatype=String.class)
})
public class Signer
	extends SignerBase
	implements Configurable
{
	Signer()
	{
		
	}
	
	public Signer(Configurator configurator)
	{
		
	}

	@Override
	public void Configure(JSONValue jsonData)
	{
		ConfigurationUtil.ConfigureUsingProperties(this, jsonData);
	}

	@Override
	public String GetConfigSectionName()
	{
		return "Signer";
	}

	public static boolean Validate(String signature,byte[] data,long validUntil)
	{
		return IOCContainer.Lookup(Signer.class).ValidateImpl(signature, data, validUntil);
	}
	
	public static boolean Validate(String signature,byte[] data)
	{
		return IOCContainer.Lookup(Signer.class).ValidateImpl(signature, data);
	}
	
	private boolean ValidateImpl(String signature,byte[] data,long validUntil)
	{
		return (System.currentTimeMillis() < validUntil) && signature.equals(SignImpl(data,validUntil));
	}
	
	private boolean ValidateImpl(String signature,byte[] data)
	{
		return signature.equals(SignImpl(data));
	}
	
	public static String Sign(byte[]data)
	{
		return IOCContainer.Lookup(Signer.class).SignImpl(data);
	}
	
	public static String Sign(byte[]data,long validUntil)
	{
		return IOCContainer.Lookup(Signer.class).SignImpl(data,validUntil);
	}
	
	private String SignImpl(byte[] data)
	{
		return MD5.Hash(new byte[][]{GetSecret().getBytes(),data});
	}

	private String SignImpl(byte[] data,long validUntil)
	{
		return MD5.Hash(new byte[][]{GetSecret().getBytes(),Long.toString(validUntil).getBytes(),data});
	}
}
